<?php

namespace App\Services;

use App\Common\Libs\ArrayHelper;
use App\Common\Libs\Dispatch\Console;
use App\Common\Libs\Json;
use App\Console\Commands\Controller\RepairArticleSrcCommand;
use App\Consts\GlobalConsoleConst;
use App\Consts\GlobalConst;
use App\Consts\GlobalSpiderConst;
use App\Models\SpiderOriginal;
use App\Models\SysArticle;
use Illuminate\Support\Facades\Log;

class SpiderService extends BaseService
{
    private $_repository;

    public function __construct()
    {
        parent::__construct();
        $this->_repository = repository()->SpiderRepository;
    }

    public function createSpiderContent($params)
    {
        return $this->_repository->createSpiderContent($params);
    }

    public function getSpiderScriptParams($url, $path, $formatUrl = '')
    {
        $query = '';
        if (strpos($url, '?') !== false) {
            $query = json_encode(parse_url($url)['query'], JSON_UNESCAPED_UNICODE);
            $url = substr($url, 0, strpos($url, '?'));
        }
        return [
            'path' => base_path('scripts/spider/') . $path,
            'baseUrl' => $url,
            'query' => $query,
            'formatUrl' => $formatUrl,
        ];
    }

    /**
     * 获取爬虫结果
     * @param $url
     * @param int $userId
     * @return array|bool
     */
    public function getSpiderScriptResult($url, $userId = '')
    {
        $spiderOriginal = SpiderOriginal::getInstance()
            ->select(['id', 'script_name'])
            ->where(['base_url' => parse_url(strtolower($url))['host']])
            ->where(['status' => GlobalSpiderConst::STATUS_NORMAL, 'is_deleted' => GlobalConst::IS_NOT_DELETE])
            ->first();
        // 调用脚本所需参数
        $params = $this->getSpiderScriptParams($url, $spiderOriginal->script_name);
        // 获取爬虫结果
        $env = config('app.env');
        exec(GlobalConst::EXEC_PYTHON . " {$params['path']} {$params['baseUrl']} {$params['formatUrl']} {$params['query']} {$env} 2>&1", $htmlJson, $res);
        Log::channel('spider')->info(__CLASS__ . " : " . __LINE__ . ' - ' . json_encode(['params' => $params, 'result' => $htmlJson]));
        $spiderResult = Json::decode($htmlJson[0] ?? '', true);
        if (!$spiderResult) {
            // 记录抓取日志
            $this->LogSpiderService->addByConsole([
                'user_id' => $userId,
                'url' => $url,
            ]);
            return false;
        }

        Console::getInstance(RepairArticleSrcCommand::class)
            ->push([
                'content' => $spiderResult['content'],
                'url' => $url
            ], GlobalConsoleConst::ARTICLE_IMAGE_MAP);

        return ArrayHelper::merge($spiderResult, [
            'spider_original_id' => $spiderOriginal->id,
            'original_created_at' => substr($spiderResult['public_time'], 0, 10),
            'url' => $url,
            'original_url' => $url,
        ]);
    }

    /**
     * 注意：
     * 文章原始链接失效，spider_info表可能没有记录
     * @param SysArticle $article
     * @return array
     */
    public function getArticleOriginalInfo($article)
    {
        $spiderInfo = $this->_repository->getSpiderInfoByUrl($article->original_url, ['spider_original_id', 'author_name', 'account_name', 'original_created_at']);

        if (!$spiderInfo) {
            $spiderOriginalId = SysArticle::getInstance($article->article_id)->where('article_id', $article->article_id)->value('spider_original_id');
            $spiderOriginal = $this->_repository->getSpiderOriginalByUrl($spiderOriginalId, ['name']);

            return [
                'name' => '',
                'from' => $spiderOriginal->name ?? '',
                'time' => '',
                'url' => $article->original_url,
            ];
        }

        $spiderOriginal = $this->_repository->getSpiderOriginalByUrl($spiderInfo->spider_original_id, ['name']);

        return [
            'author_name' => $spiderInfo->author_name,
            'account_name' => $spiderInfo->account_name,
            'from' => $spiderOriginal->name ?? '',
            'time' => $spiderInfo->original_created_at ?? '',
            'url' => $article->original_url ?? '',
        ];
    }
}
